/**
* This file is part of the Bonsai Game Library.
*
* The Bonsai Game Library is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* The Bonsai Game Library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with the Bonsai Game Library. If not, see <http://www.gnu.org/licenses/>.
*
*/
package org.bonsai.dev;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
public class GameSound extends GameComponent {
private Map<String, Class<? extends SoundObject>> soundTypes = new HashMap<String, Class<? extends SoundObject>>();
private Map<String, byte[]> sounds = new HashMap<String, byte[]>();
private Map<String, SoundObject> soundsStatus = new HashMap<String, SoundObject>();
private Map<String, Class<? extends SoundObject>> soundEngines = new HashMap<String, Class<? extends SoundObject>>();
public GameSound(final Game game) {
super(game);
}
public void addType(final String ext,
final Class<? extends SoundObject> sound) {
soundEngines.put(ext, sound);
}
public final boolean load(final String id, final String filename) {
Class<? extends SoundObject> type = null;
for (String ext : soundEngines.keySet()) {
if (filename.toLowerCase().endsWith(ext)) {
type = soundEngines.get(ext);
break;
}
}
if (type == null) {
return false;
}
try {
final InputStream stream = this.getClass().getResourceAsStream(filename);
final int size = stream.available();
final byte[] bytes = new byte[size];
int offset = 0;
int numRead;
while (offset < bytes.length
&& (numRead = stream.read(bytes, offset, bytes.length
- offset)) >= 0) {
offset += numRead;
}
sounds.put(id, bytes);
soundTypes.put(id, type);
stream.close();
return true;
} catch (Exception e) {
return false;
}
}
public final boolean isPlaying(final String id) {
if (soundsStatus.containsKey(id)) {
return soundsStatus.get(id).status == 1;
} else {
return false;
}
}
public final boolean isPaused(final String id) {
if (soundsStatus.containsKey(id)) {
return soundsStatus.get(id).status == 3;
} else {
return false;
}
}
public final void stop(final String id) {
if (soundsStatus.containsKey(id)) {
soundsStatus.get(id).status = 2;
}
}
public final void pause(final String id, final boolean pause) {
if (soundsStatus.containsKey(id)) {
if (soundsStatus.get(id).status != 2) {
soundsStatus.get(id).status = pause ? 3 : 1;
}
}
}
public final void setVolume(final String id, final float volume) {
if (soundsStatus.containsKey(id)) {
soundsStatus.get(id).volume = volume;
soundsStatus.get(id).toVolume = volume;
}
}
public final void setFadeVolume(final String id, final float volume,
final int time) {
if (soundsStatus.containsKey(id)) {
soundsStatus.get(id).toVolumeDifference = Math.abs(soundsStatus
.get(id).volume
- volume);
soundsStatus.get(id).toVolume = volume;
soundsStatus.get(id).volumeChanged = true;
soundsStatus.get(id).toVolumeTime = time;
}
}
public final boolean isSilent(final String id) {
if (soundsStatus.containsKey(id)) {
return soundsStatus.get(id).volume == 0.0f;
} else {
return true;
}
}
public final void play(final String id, final boolean stop) {
play(id, stop, false, 1.0f);
}
public final void play(final String id, final boolean stop,
final boolean loop, final float volume) {
if (game.hasSound() && sounds.containsKey(id)) {
if (isPlaying(id) && stop) {
soundsStatus.get(id).status = 2;
}
soundsStatus.put(id, null);
try {
final SoundObject snd = soundTypes.get(id).newInstance();
snd.setDaemon(true);
snd.setName(snd.getTypeName() + "-SoundThread-" + id);
snd.loop = loop;
snd.volume = volume;
snd.toVolume = volume;
snd.initSound(sounds.get(id));
snd.start();
soundsStatus.put(id, snd);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
public final boolean delete(final String id) {
if (soundsStatus.containsKey(id)) {
sounds.remove(id);
soundTypes.remove(id);
soundsStatus.remove(id);
return true;
} else {
return false;
}
}
public final void stopAll() {
for (String id : sounds.keySet()) {
stop(id);
}
}
public final void pauseAll(final boolean mode) {
for (String id : sounds.keySet()) {
pause(id, mode);
}
}
public final boolean init() {
final AudioFormat[] formats = new AudioFormat[] {
new AudioFormat(44100.0f, 16, 2, true, false),
new AudioFormat(22050.0f, 16, 2, true, false),
new AudioFormat(11050.0f, 16, 2, true, false) };
for (AudioFormat format : formats) {
try {
DataLine.Info info = new DataLine.Info(SourceDataLine.class,
format);
SourceDataLine line = (SourceDataLine) AudioSystem
.getLine(info);
line.open(format);
line.start();
line.close();
return true;
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}
}